#!/usr/bin/env python
# -*- coding: utf-8 -*-

import cherrypy

from farado.logger import logger
from farado.ui.renderer import view_renderer
from farado.helpers.cookie_helper import current_session_id
from farado.general_manager_holder import project_manager, permission_manager
from farado.items.board import Board
from farado.items.board_column import BoardColumn
from farado.ui.operation_result import OperationResult
from farado.ui.base_view import BaseView, UiUserRestrictions
from farado.ui.base_view import bring_value, get_value



class BoardsView(BaseView):

    #--------------------------------------------------------------------------#
    def __init__(self):
        super().__init__()
        self.name = '/boards'

    #--------------------------------------------------------------------------#
    @cherrypy.expose
    def index(self):
        user = self.current_user()
        if not user:
            return self.login_and_open()

        operation_result = user.pop_last_action_result()

        message = f"Открытие страницы с перечнем досок."
        logger.info(f"%-18s | {message}", user.login)

        return view_renderer["boards"].render(
            user=user,
            project_manager=project_manager(),
            operation_result=operation_result,
            restriction=UiUserRestrictions(
                is_admin=self.is_admin(user.id),
            )
        )

    #--------------------------------------------------------------------------#
    @cherrypy.expose
    def board(self, target_board_id=None, function=None, **args):
        user = self.current_user()
        if not user:
            if target_board_id:
                return self.login_and_open(f'/board/{target_board_id}', args)
            return self.login_and_open()

        if function:
            result_code, result_text, target_id = self.process_function(
                user,
                function
            )
            user.push_last_action_result(
                OperationResult(
                    caption=result_text,
                    result_code=result_code,
                )
            )
            message = f"выполнение функции: {result_text} #{target_id}."
            if result_code:
                logger.info(f"%-18s | Удачное {message}", user.login)
            else:
                logger.warn(f"%-18s | Неудачное {message}", user.login)

        args = bring_value(user.pop_last_action_data(), args)
        is_reading = bool(len(args) == 0)

        # TODO : rights

        target_board = project_manager().board(target_board_id)
        if not target_board and is_reading:
            message = f"Доска #{target_board_id} не найдена."
            logger.warn(f"%-18s | {message}.", user.login)
            raise cherrypy.HTTPError(404, message)

        operation_result = user.pop_last_action_result()
        # TODO : Перенести сохранение доски в класс-редактор
        if not is_reading:
            if not target_board:
                if not self.is_admin(user.id):
                    message = f"Нет прав на изменение доски #{target_board_id}."
                    logger.warn(f"%-18s | {message}", user.login)
                    raise cherrypy.HTTPError(403, message)

                target_board = Board()
                logger.info(f"%-18s | Создание новой доски.", user.login)

            if 'target_board_caption' in args:
                target_board.caption = args['target_board_caption']

            if 'target_board_description' in args:
                target_board.description = args['target_board_description']

            if 'target_board_workflow_id' in args:
                target_board_workflow_id = args['target_board_workflow_id']
                if target_board_workflow_id.isdigit() and bool(int(target_board_workflow_id)):
                    target_board.workflow_id = int(target_board_workflow_id)

            target_board.set_filter_by_key(
                Board.FilterKey.kinds_ids,
                get_value(args, 'filter_kinds_ids', [])
            )
            target_board.set_filter_by_key(
                Board.FilterKey.projects_ids,
                get_value(args, 'filter_projects_ids', [])
            )
            target_board.set_filter_by_key(
                Board.FilterKey.versions_ids,
                get_value(args, 'filter_versions_ids', [])
            )

            # To get target_board_id we must save the new item
            if not target_board_id:
                project_manager().save_item(target_board)
            self.save_board_columns(target_board.id, args)

            message = f"Сохранение доски #{target_board.id} «{target_board.caption}»."
            logger.info(f"%-18s | {message}", user.login)

            project_manager().save_item(target_board)
            operation_result = OperationResult(
                caption="Доска сохранена",
                kind="success"
            )

        message = f"Открытие страницы доски #{target_board.id} «{target_board.caption}»."
        logger.info(f"%-18s | {message}", user.login)

        return view_renderer["board"].render(
            user=user,
            project_manager=project_manager(),
            target_board=target_board,
            operation_result=operation_result,
            restriction=UiUserRestrictions(
                is_admin=self.is_admin(user.id),
            )
        )

    #--------------------------------------------------------------------------#
    def save_board_columns(self, target_board_id, args):
        # Prepare board column property values
        board_column_properties = {}
        for key, value in args.items():
            if not key.startswith("board_column"):
                continue
            key_data = key.split("_")
            board_column_id = key_data[-1]
            board_column_field = "_".join(key_data[2:-1])
            if not board_column_id in board_column_properties:
                board_column_properties[board_column_id] = {}
            board_column_properties[board_column_id][board_column_field] = value

        # Apply rules property changes
        for board_column_id, properties in board_column_properties.items():
            board_column = project_manager().board_column(board_column_id)
            board_column.reset_properties(properties)
            board_column.board_id = target_board_id
            project_manager().save_item(board_column)

        # Remove deleted rules
        for board_column in project_manager().board_columns_by_board(target_board_id):
            if str(board_column.id) in board_column_properties:
                continue
            project_manager().remove_item(BoardColumn, board_column.id)

    #--------------------------------------------------------------------------#
    @cherrypy.expose
    def add_board(self):
        user = self.current_user()
        if not user:
            return self.login_and_open('/add_board')

        if not self.is_admin(user.id):
            message = f"Нет прав на создание досок."
            logger.warn(f"%-18s | {message}", user.login)
            raise cherrypy.HTTPError(403, message)

        message = f"Открытие страницы создания новой доски."
        logger.info(f"%-18s | {message}", user.login)

        return view_renderer["new_board"].render(
            user=user,
            project_manager=project_manager(),
            target_board=Board(),
            save_result=None,
            restriction=UiUserRestrictions(
                is_admin=self.is_admin(user.id),
            )
        )

    #--------------------------------------------------------------------------#
    @cherrypy.expose
    def remove_board(self, target_board_id):
        user = self.current_user()
        if not user:
            return self.login_and_open(f'/remove_board/{target_board_id}')

        if not self.is_admin(user.id):
            message = f"Нет прав на удаление доски #{target_board_id}."
            logger.warn(f"%-18s | {message}.", user.login)
            raise cherrypy.HTTPError(403, message)

        logger.info(f"%-18s | Удаление доски #{target_board_id}.", user.login)
        project_manager().remove_item(Board, target_board_id)

        user.push_last_action_result(
            OperationResult(
                caption="Доска удалена",
                kind="success"
            )
        )
        raise cherrypy.HTTPRedirect(cherrypy.url(f'/'))

    #--------------------------------------------------------------------------#
    @cherrypy.expose
    def add_board_column(self, target_board_id):
        user = self.current_user()
        if not user:
            return self.login_and_open(f'/add_board_column/{target_board_id}')

        is_admin = self.is_admin(user.id)
        if not is_admin:
            message = f"Нет прав на изменение доски #{target_board_id}."
            logger.warn(f"%-18s | {message}.", user.login)
            raise cherrypy.HTTPError(403, message)

        if not project_manager().board(target_board_id):
            message = f"Доска не найдена #{target_board_id}."
            logger.warn(f"%-18s | {message}.", user.login)
            raise cherrypy.HTTPError(404, message)

        board_column = BoardColumn()
        board_column.board_id = target_board_id

        project_manager().save_item(board_column)

        message = f"Добавлен новый столбец на доску #{target_board_id}."
        logger.info(f"%-18s | {message}", user.login)

        user.push_last_action_result(
            OperationResult(
                caption="Добавлен новый столбец на доску",
                kind="success"
            )
        )
        raise cherrypy.HTTPRedirect(cherrypy.url(f'/board/{target_board_id}'))
